<file>logged-in-indicator.svg</file>
<file>more-results.svg</file>
<file>no-events.svg</file>
+ <file>no-notifications.svg</file>
<file>noise-texture.png</file>
<file>page-indicator-active.svg</file>
<file>page-indicator-inactive.svg</file>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="64px"
+ height="64px"
+ id="svg3393"
+ version="1.1"
+ inkscape:version="0.48.5 r10040"
+ sodipodi:docname="New document 2">
+ <defs
+ id="defs3395" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.5"
+ inkscape:cx="32"
+ inkscape:cy="32"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="697"
+ inkscape:window-height="613"
+ inkscape:window-x="100"
+ inkscape:window-y="77"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata3398">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <g
+ style="display:inline"
+ transform="matrix(4,0,0,4,0.29733827,-0.35415646)"
+ id="g19245">
+ <g
+ id="g19247"
+ inkscape:label="status"
+ style="display:inline"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19249"
+ inkscape:label="devices"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19251"
+ inkscape:label="apps"
+ transform="translate(-323.02908,-649.02581)">
+ <path
+ inkscape:connector-curvature="0"
+ d="m 331.9377,653 c 0.0187,0.16677 0.0625,0.32822 0.0625,0.5 0,2.48528 -2.01472,4.5 -4.5,4.5 -0.11769,0 -0.22834,-0.0224 -0.34375,-0.0312 l 0,2.21875 c 0,1.00412 0.80838,1.8125 1.8125,1.8125 l 1.54511,-5e-5 2,2.04688 2.0625,-2.04688 1.61114,0 c 1.00413,0 1.8125,-0.80838 1.8125,-1.8125 l 0,-5.375 c 0,-1.00412 -0.80837,-1.8125 -1.8125,-1.8125 z"
+ id="path19253"
+ sodipodi:nodetypes="csscsscccssssc"
+ style="opacity:0.5;color:#000000;fill:#c3c3c3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 327.5002,650 c -1.933,0 -3.5,1.567 -3.5,3.5 0,1.933 1.567,3.5 3.5,3.5 1.933,0 3.5,-1.567 3.5,-3.5 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m -0.53125,1 1.03125,0 -0.0625,1.375 a 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.125,0.125 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 l 1.15625,-0.75 0.5,0.90625 -1.21875,0.625 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0.0937 0.19951718,0.19951718 0 0 0 0,0.0625 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0625 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0312,0.0312 l 1.25,0.625 -0.53125,0.90625 -1.15625,-0.781 a 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,0 0.19951718,0.19951718 0 0 0 -0.125,0.0937 0.19951718,0.19951718 0 0 0 -0.0312,0.0312 0.19951718,0.19951718 0 0 0 0,0.0312 0.19951718,0.19951718 0 0 0 0,0.0625 l 0.0625,1.3751 -1.03125,0 0.0937,-1.375 a 0.19951718,0.19951718 0 0 0 -0.0312,-0.0937 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0625,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 0.19951718,0.19951718 0 0 0 -0.0937,0.0312 l -1.1875,0.78125 -0.5,-0.90625 1.25,-0.625 a 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,-0.0625 0.19951718,0.19951718 0 0 0 -0.0312,-0.0312 0.19951718,0.19951718 0 0 0 -0.0312,0 l -1.25,-0.625 0.5,-0.90625 1.1875,0.75 a 0.19951718,0.19951718 0 0 0 0.0312,0.0312 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0625,0 0.19951718,0.19951718 0 0 0 0.0312,0 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0312 0.19951718,0.19951718 0 0 0 0,-0.0312 0.19951718,0.19951718 0 0 0 0.0312,-0.0625 0.19951718,0.19951718 0 0 0 0,-0.0312 L 326.96895,651 z"
+ id="path19255"
+ style="color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+ <g
+ id="g19257"
+ inkscape:label="places"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19259"
+ inkscape:label="mimetypes"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19261"
+ inkscape:label="emblems"
+ style="display:inline"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19263"
+ inkscape:label="emotes"
+ style="display:inline"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19265"
+ inkscape:label="categories"
+ style="display:inline"
+ transform="translate(-323.02908,-649.02581)" />
+ <g
+ id="g19267"
+ inkscape:label="actions"
+ style="display:inline"
+ transform="translate(-323.02908,-649.02581)" />
+ </g>
+ </g>
+</svg>
const Shell = imports.gi.Shell;
const Main = imports.ui.main;
+const MessageTray = imports.ui.messageTray;
const Tweener = imports.ui.tweener;
const Util = imports.misc.util;
});
Signals.addSignalMethods(Message.prototype);
+const NotificationMessage = new Lang.Class({
+ Name: 'NotificationMessage',
+ Extends: Message,
+
+ _init: function(notification) {
+ this.notification = notification;
+
+ this.setUseBodyMarkup(notification.bannerBodyMarkup);
+ this.parent(notification.title, notification.bannerBodyText);
+
+ this.setIcon(this._getIcon());
+
+ this.connect('close', Lang.bind(this,
+ function() {
+ this._closed = true;
+ this.notification.destroy(MessageTray.NotificationDestroyedReason.DISMISSED);
+ }));
+ notification.connect('destroy', Lang.bind(this,
+ function() {
+ if (!this._closed)
+ this.emit('close');
+ }));
+ this._updatedId = notification.connect('updated',
+ Lang.bind(this, this._onUpdated));
+ },
+
+ _getIcon: function() {
+ if (this.notification.gicon)
+ return new St.Icon({ gicon: this.notification.gicon, icon_size: 48 });
+ else
+ return this.notification.source.createIcon(48);
+ },
+
+ _onUpdated: function(n, clear) {
+ this.setIcon(this._getIcon());
+ this.setTitle(n.title);
+ this.setBody(n.bannerBodyText);
+ this.setUseBodyMarkup(n.bannerBodyMarkup);
+ },
+
+ canClear: function() {
+ return !this.notification.resident;
+ },
+
+ _onClicked: function() {
+ this.notification.activate();
+ },
+
+ _onDestroy: function() {
+ if (this._updatedId)
+ this.notification.disconnect(this._updatedId);
+ this._updatedId = 0;
+ }
+});
+
const MessageListSection = new Lang.Class({
Name: 'MessageListSection',
}
});
+const NotificationSection = new Lang.Class({
+ Name: 'NotificationSection',
+ Extends: MessageListSection,
+
+ _init: function() {
+ this.parent('Notifications');
+
+ this._sources = new Map();
+ this._nUrgent = 0;
+
+ Main.messageTray.connect('source-added', Lang.bind(this, this._sourceAdded));
+ Main.messageTray.getSources().forEach(Lang.bind(this, function(source) {
+ this._sourceAdded(Main.messageTray, source);
+ }));
+
+ this.actor.connect('notify::mapped', Lang.bind(this, this._onMapped));
+
+ Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
+ this._sessionUpdated();
+ },
+
+ _sourceAdded: function(tray, source) {
+ let obj = {
+ destroyId: 0,
+ notificationAddedId: 0,
+ };
+
+ obj.destroyId = source.connect('destroy', Lang.bind(this, function(source) {
+ this._onSourceDestroy(source, obj);
+ }));
+ obj.notificationAddedId = source.connect('notification-added',
+ Lang.bind(this, this._onNotificationAdded));
+
+ this._sources.set(source, obj);
+ },
+
+ _onNotificationAdded: function(source, notification) {
+ let message = new NotificationMessage(notification);
+
+ let time = new Date().toLocaleFormat(C_("event list time", "%H\u2236%M"));
+ message.setSecondaryActor(new St.Label({ style_class: 'event-time',
+ x_align: Clutter.ActorAlign.END,
+ text: time }));
+
+ let isUrgent = notification.urgency == MessageTray.Urgency.CRITICAL;
+ if (isUrgent) {
+ // Keep track of urgent notifications to keep them on top
+ this._nUrgent++;
+
+ let id = notification.connect('destroy', Lang.bind(this,
+ function() {
+ notification.disconnect(id);
+ this._nUrgent--;
+ }));
+ } else if (this.mapped) {
+ // Only acknowledge non-urgent notifications in case it
+ // has important actions that are inaccessible when not
+ // shown as banner
+ notification.acknowledged = true;
+ }
+
+ let index = isUrgent ? 0 : this._nUrgent;
+ this.addMessageAtIndex(message, index, this.actor.mapped);
+ },
+
+ _onSourceDestroy: function(source, obj) {
+ source.disconnect(obj.destroyId);
+ source.disconnect(obj.notificationAddedId);
+
+ this._sources.delete(source);
+ },
+
+ _onMapped: function() {
+ if (!this.actor.mapped)
+ return;
+
+ for (let message of this._messages.keys())
+ if (message.notification.urgency != MessageTray.Urgency.CRITICAL)
+ message.notification.acknowledged = true;
+ },
+
+ _onTitleClicked: function() {
+ this.parent();
+
+ let app = Shell.AppSystem.get_default().lookup_app('gnome-notifications-panel.desktop');
+
+ if (!app) {
+ log('Settings panel for desktop file ' + desktopFile + ' could not be loaded!');
+ return;
+ }
+
+ app.activate();
+ },
+
+ _syncVisible: function() {
+ this.actor.visible = !this.empty && this._isToday();
+ },
+
+ _sessionUpdated: function() {
+ this._title.reactive = Main.sessionMode.allowSettings;
+ }
+});
+
const Placeholder = new Lang.Class({
Name: 'Placeholder',
this._date = new Date();
- let file = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-events.svg');
- let gicon = new Gio.FileIcon({ file: file });
+ let todayFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-notifications.svg');
+ let otherFile = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/no-events.svg');
+ this._todayIcon = new Gio.FileIcon({ file: todayFile });
+ this._otherIcon = new Gio.FileIcon({ file: otherFile });
- this._icon = new St.Icon({ gicon: gicon });
+ this._icon = new St.Icon();
this.actor.add_actor(this._icon);
- this._label = new St.Label({ text: _("No Events") });
+ this._label = new St.Label();
this.actor.add_actor(this._label);
+
+ this._sync();
+ },
+
+ setDate: function(date) {
+ if (_sameDay(this._date, date))
+ return;
+ this._date = date;
+ this._sync();
+ },
+
+ _sync: function() {
+ let isToday = _sameDay(this._date, new Date());
+ if (isToday && this._icon.gicon == this._todayIcon)
+ return;
+ if (!isToday && this._icon.gicon == this._otherIcon)
+ return;
+
+ if (isToday) {
+ this._icon.gicon = this._todayIcon;
+ this._label.text = _("No Notifications");
+ } else {
+ this._icon.gicon = this._otherIcon;
+ this._label.text = _("No Events");
+ }
}
});
this._scrollView.add_actor(this._sectionList);
this._sections = new Map();
+ this._notificationSection = new NotificationSection();
+ this._addSection(this._notificationSection);
+
this._eventsSection = new EventsSection();
this._addSection(this._eventsSection);
},
setDate: function(date) {
for (let section of this._sections.keys())
section.setDate(date);
+ this._placeholder.setDate(date);
}
});
if (LoginManager.canLock())
screenShield = new ScreenShield.ScreenShield();
- panel = new Panel.Panel();
messageTray = new MessageTray.MessageTray();
+ panel = new Panel.Panel();
keyboard = new Keyboard.Keyboard();
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();